home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HamCall (October 1991)
/
HamCall (Whitehall Publishing)(1991).bin
/
prgming
/
ada
/
pnote1.doc
< prev
next >
Wrap
Text File
|
1987-10-14
|
5KB
|
109 lines
5-Apr-86 14:51:29-MST,4792;000000000001
Return-Path: <@USC-ISIF.ARPA:info-ada-request@usc-isif.arpa>
Received: from USC-ISIF.ARPA by SIMTEL20.ARPA with TCP; Sat 5 Apr 86 14:51:20-MST
Received: FROM berkeley BY USC-ISIF.ARPA WITH TCP ; 5 Apr 86 13:10:48 PST
Received: by ucbvax.berkeley.edu (5.48/1.11)
id AA01699; Sat, 5 Apr 86 12:34:03 PST
Date: 4 Apr 86 13:36:35 GMT
From: sftig!sfsup!sfmag!sftor!cw@ucbvax.berkeley.edu (C.S.Wetherell)
Organization: AT&T Bell Laboratories, Summit N.J.
Subject: Two characteristic programming errors in Ada
Message-Id: <951@sftor.UUCP>
Sender: postmaster@usc-isif.arpa (fix your mailer)
Real-Annoyed-Sender: usenet@ucbvax.berkeley.edu
Errors-To: <info-ada-request@usc-isif.arpa>
To: info-ada@usc-isif.arpa
While porting some programs from the Simtel20 archives to our new
compiler, I had some difficulty with one of them. Upon investigation,
I discovered two subtle but characteristic misuses of Ada. I am sure they
are quite common, so I will protect the author.
Consider the following procedure declaration (ignore its innards for
the moment)
procedure Does_A_Check(Formal : in out NATURAL);
and the skeletal calling routine
with Does_A_Check;
procedure Im_A_Caller is
Actual : NATURAL;
begin
Does_A_Check(Actual);
end;
When this pair was linked and executed, a constraint exception was raised at
the point of call. [This happened to be particularly mystifying in the
ported program, because the program was carefully taking care of all
exceptions and I couldn't tell at first exactly what was causing the
program to fail. Some embedding of trace statements uncovered the
difficulty after a bit.] Of course, the reason the constraint error
was raised was that variable Actual in Im_A_Caller was not
initialized; there is no requirement that the initial value of
a variable be within its declared bounds (with exception of access
types, of course). Since formal in-out parameters are checked
for constraints at procedure entry, a constraint error was raised.
I can only assume that the particular program had always been compiled
and executed on a system where the initial values were within bounds;
this is, of course, an example of a bug common to other languages as
well.
However, there is a second bug in the program. Let us now
consider the body of Does_A_Check:
procedure Does_A_Check(Formal : in out NATURAL) is
begin
Formal := 0;
...
Something := ... Formal ...;
...
end;
Notice that the first thing Does_A_Check executes is an initializing
assignment to Formal; the routine really doesn't care about the
in-bound value of the actual argument at all. In fact, the only
reason that Formal is declared "in out" is so that it can be used
on the right-hand side of some statements. Now, the Ada rule is that
an "out" parameter cannot be so used; the parameter may have an
undefined value at some places of such usage and the rules about
no right-hand usage keep the compiler from having to do a flow
analysis to determine if a particular usage is after a definition.
Here, the programmer, to save declaring a local variable, just made
Formal "in out"; then it can be used on the right. But the cost is
unexpected constraint errors or extra work for the caller;
after all, the caller doesn't know (in theory) why the formal parameter
is "in out" and may have to go to considerable trouble to guarantee that
the actual argument has an acceptable value; this is disturbing when
the formal doesn't really need the initial value.
The moral seems to be to use "in out" parameters only when the
called routine actually needs the initial value; otherwise, use
a paradigm like
procedure Does_A_Check(Formal : out NATURAL) is
Local : NATURAL;
begin
Local := 0; -- yes, this could be done in the declaration.
...
Something := ... Local ...
...
Formal := Local;
return;
end Does_A_Check;
Finally, I might note that this problem was uncovered partly because our
compiler temporarily is storing characters in 16-bits while a little
part of our code generator is undergoing additional education about
the differences between signed and unsigned bytes. One version of the
problem was using characters instead of NATURAL's. If the Actual
from above had been an 8-bit character, it might have been automatically
truncated to within the constraints; as a 16-bit character, it was not.
There is no guarantee in Ada about the sizes of types beyond the rules
governing type declarations; this particular stretch of code was
mildly unrobust in the face of changing sizes
Charles Wetherell
AT&T Information Systems
Summit NJ